﻿package com.gengine.utils
{

    public class Arithmetic extends Object
    {

        public function Arithmetic()
        {
            return;
        }// end function

        private static function isStart(param1:String, param2:int) : Boolean
        {
            return param2 <= 0 || param1.charAt((param2 - 1)) == "(";
        }// end function

        private static function isOperator(param1:String, param2:int) : Boolean
        {
            if (param2 >= param1.length || param2 < 0)
            {
                return false;
            }
            if (isStart(param1, param2))
            {
                return false;
            }
            var _loc_3:* = param1.charAt(param2);
            return _loc_3 == "+" || _loc_3 == "-" && !isOperator(param1, (param2 - 1)) || _loc_3 == "*" || _loc_3 == "/" || _loc_3 == "%";
        }// end function

        private static function isNumber(param1:String, param2:int) : Boolean
        {
            if (param2 >= param1.length || param2 < 0)
            {
                return false;
            }
            var _loc_3:* = param1.charAt(param2);
            return _loc_3 >= "0" && _loc_3 <= "9" || _loc_3 == "." || _loc_3 == "-" && (isOperator(param1, (param2 - 1)) || isStart(param1, param2));
        }// end function

        private static function getPriority(param1:String) : int
        {
            switch(param1)
            {
                case ")":
                {
                    return 3;
                }
                case "*":
                case "/":
                case "%":
                {
                    return 2;
                }
                case "+":
                case "-":
                {
                    return 1;
                }
                case "(":
                {
                    return -1;
                }
                default:
                {
                    return 0;
                    break;
                }
            }
        }// end function

        private static function getValue(param1:String, param2:Number, param3:Number) : Number
        {
            switch(param1)
            {
                case "*":
                {
                    return param3 * param2;
                }
                case "%":
                {
                    return param3 % param2;
                }
                case "/":
                {
                    return param3 / param2;
                }
                case "-":
                {
                    return param3 - param2;
                }
                case "+":
                {
                    return param3 + param2;
                }
                default:
                {
                    break;
                }
            }
            return NaN;
        }// end function

        public static function exec(param1:String) : Number
        {
            var _loc_4:String = null;
            var _loc_5:Number = NaN;
            var _loc_6:Number = NaN;
            var _loc_8:String = null;
            var _loc_9:String = null;
            var _loc_2:Array = [];
            var _loc_3:Array = [];
            var _loc_7:int = 0;
            while (_loc_7 < param1.length)
            {
                
                _loc_8 = param1.charAt(_loc_7);
                if (_loc_8 == " ")
                {
                    _loc_7++;
                }
                if (_loc_8 == "(")
                {
                    _loc_2.push(_loc_8);
                    _loc_7++;
                    continue;
                }
                if (_loc_8 == ")")
                {
                    _loc_4 = _loc_2.pop();
                    while (_loc_4 != "(")
                    {
                        
                        _loc_5 = _loc_3.pop();
                        _loc_6 = _loc_3.pop();
                        _loc_3.push(getValue(_loc_4, _loc_5, _loc_6));
                        _loc_4 = _loc_2.pop();
                    }
                    _loc_7++;
                    continue;
                }
                if (isOperator(param1, _loc_7))
                {
                    while (getPriority(_loc_8) <= getPriority(_loc_2[(_loc_2.length - 1)]) && _loc_2.length)
                    {
                        
                        _loc_4 = _loc_2.pop();
                        _loc_5 = _loc_3.pop();
                        _loc_6 = _loc_3.pop();
                        _loc_3.push(getValue(_loc_4, _loc_5, _loc_6));
                    }
                    _loc_2.push(param1.charAt(_loc_7));
                    _loc_7++;
                    continue;
                }
                _loc_9 = "";
                while (isNumber(param1, _loc_7) && _loc_7 < param1.length)
                {
                    
                    _loc_9 = _loc_9 + param1.charAt(_loc_7);
                    _loc_7++;
                }
                _loc_3.push(Number(_loc_9));
            }
            while (_loc_2.length)
            {
                
                _loc_4 = _loc_2.pop();
                _loc_5 = _loc_3.pop();
                _loc_6 = _loc_3.pop();
                _loc_3.push(getValue(_loc_4, _loc_5, _loc_6));
            }
            return _loc_3.pop();
        }// end function

    }
}
